package com.yumeng.framework.persistence.mybatis.plugins.dynamictable;

import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.yumeng.common.exception.YumengException;
import com.yumeng.framework.persistence.mybatis.plugins.dynamictable.parser.AbstractTableNameMapParser;
import com.yumeng.framework.persistence.mybatis.plugins.dynamictable.parser.DateTableNameParser;
import com.yumeng.framework.persistence.mybatis.plugins.dynamictable.parser.IdModTableNameParser;
import org.apache.commons.collections4.MapUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 动态表名处理器
 *
 * @author wxd
 * @date 2022/9/2 9:28
 */
public class SimpleTableNameHandler implements TableNameHandler {

    private final Map<DynamicTableNameMode, AbstractTableNameMapParser> tableNameParserMap;
    private final Map<String, DynamicTableNameMode> tableNameModeMap;//表名与对应的动态表名模式映射

    public SimpleTableNameHandler(Map<String, Integer> idModModeMap, Map<String, TableNameDateSuffixType> dateModeMap){
        tableNameParserMap = new HashMap<>();
        tableNameModeMap = new HashMap<>();
        //判断不同动态表名映射模式表名称冲突，并初始化Parser
        int targetLen = 0;

        //ID取模
        IdModTableNameParser idModTableNameParser;
        if (MapUtils.isNotEmpty(idModModeMap)){
            targetLen += idModModeMap.size();
            idModTableNameParser = new IdModTableNameParser(idModModeMap);
            tableNameParserMap.put(DynamicTableNameMode.ID_MOD, idModTableNameParser);
            idModModeMap.keySet().forEach(p-> tableNameModeMap.put(p, DynamicTableNameMode.ID_MOD));
        }

        //日期模式
        DateTableNameParser dateTableNameParser;
        if (MapUtils.isNotEmpty(dateModeMap)){
            targetLen += dateModeMap.size();
            dateTableNameParser = new DateTableNameParser(dateModeMap);
            tableNameParserMap.put(DynamicTableNameMode.DATE, dateTableNameParser);
            dateModeMap.keySet().forEach(p-> tableNameModeMap.put(p, DynamicTableNameMode.DATE));
        }

        if (MapUtils.isEmpty(tableNameParserMap)){
            throw new YumengException("请配置动态表名映射信息");
        }
        if (tableNameModeMap.size() != targetLen){
            throw new YumengException("不同模式动态表名映射中表名冲突");
        }
    }

    /**
     * 验证表名是否存在
     * @param tableName
     * @return
     */
    public boolean checkContains(String tableName){
        DynamicTableNameMode mode = tableNameModeMap.get(tableName);
        if (mode == null){
            return false;
        }
        return true;
    }

    /**
     * 验证表名是否存在
     * @param tableName
     * @return
     */
    public boolean checkContains(String tableName, DynamicTableNameMode mode){
        AbstractTableNameMapParser parser = tableNameParserMap.get(mode);
        if (parser == null){
            return false;
        }
        return parser.checkContains(tableName);
    }

    /**
     * 根据模式获取TableNameParser
     *
     * @param mode
     * @return
     */
    public AbstractTableNameMapParser getAbstractTableNameParser(DynamicTableNameMode mode){
        AbstractTableNameMapParser parser = tableNameParserMap.get(mode);
        if (parser == null){
            throw new YumengException("请配置【%s】表名处理器", mode.getDesc());
        }
        return parser;
    }

    /**
     * 生成动态表名
     *
     * @param sql       当前执行 SQL
     * @param tableName 表名
     * @return String
     */
    @Override
    public String dynamicTableName(String sql, String tableName) {
        DynamicTableNameMode mode = tableNameModeMap.get(tableName);
        if (mode == null){
            return tableName;
        }
        //已经根据表名找到对应的处理器类型，因此此处parser肯定存在
        AbstractTableNameMapParser parser = tableNameParserMap.get(mode);
        return parser.dynamicTableName(sql, tableName);

    }

}
